function Disk(config, host) {
	ARG_CHECK(2, 4);
	this.config = config;
	this.used = config.used ? config.used : 0;
	this.host = host;
	
	var nDisks = config.nDisks ? config.nDisks : 1;
	this.fac = new Sim.Facility('disk', Sim.Facility.FIFO, nDisks);
	this.inodes = {};
}

Disk.Inode = function (data, size) {
	ARG_CHECK(arguments, 2, 2);
	this.data = data;
	this.size = size;
	this.error = false;
};

Disk.prototype = {
	fileExists: function (filename) {
		return !!this.inodes[filename];
	},
	
	getInode: function (filename) {
		return this.inodes[filename];
	},
	
	setFileData: function (filename, data) {
		ARG_CHECK(arguments, 2, 2);
		var inode = this.inodes[filename];
		if (inode) {
			inode.data = data;
		}
	},
	
	getFileData: function (filename) {
		ARG_CHECK(arguments, 1, 1);
		var inode = this.inodes[filename];
		return inode ? inode.data : null;
	},
	
	getFilesize: function (filename) {
		ARG_CHECK(arguments, 1, 1);
		var inode = this.inodes[filename];
		return inode ? inode.size : NaN;
	},

	create: function (filename, data) {
		ARG_CHECK(arguments, 1, 2);

		var inode = this.inodes[filename];
		if (inode) { return false; }
		
		this.inodes[filename] = new Disk.Inode(data, 0);
	},

	append: function (filename, size) {
		ARG_CHECK(arguments, 2, 5);
		if (this.used + size > this.config.capacity) {
			return null;
		}

		var inode = this.inodes[filename];
		if (!inode) {
			return null;
		}

		if (size > 0) {
			var time = this.config.accessTime + size / this.config.writeThput;
			return this.host.useFacility(this.fac, time)
			.done(function (inode, size) {
				inode.size += size;
				this.used += size;
			}, this, [inode, size]);
		}
		
		return null;
	},

	read: function (filename, size) {
		var inode = this.inodes[filename];
		if (!inode) { return null; }
		if (!size) size = inode.size;

		var time = this.config.accessTime + size / this.config.readThput;
		return this.host.useFacility(this.fac, time);
	},

	remove: function (filename) {
		var inode = this.inodes[filename];
		if (inode) {
			this.used -= inode.size;
			this.inodes[filename] = null;
		}
	},
	
	wipe: function () {
		this.used = config.used ? config.used : 0;
		this.fac.clear();
		this.inodes = {};
	},
	
	corrupt: function (filename) {
		var inode = this.inodes[filename];
		if (inode) {
			inode.error = true;
		}	
	},
	
	report: function (writer) {
		writer("Disk at host Id=" + this.host.id);
		for (var filename in this.inodes) {
			var inode = this.inodes[filename];
			writer("    " + filename + ": size=" + inode.size);
		}
	}
};